Correctness and performance are separate; indexing is invisible in results
The two queries return the same results because the filter semantics are identical: both evaluate the predicate against the payload and return the points that match. The difference is in how the predicate is evaluated. With an indexed field, the planner can use the index to resolve the filter efficiently: it can look up the matching points in the posting list (for a keyword index), prune segments whose index shows no matching points, and guide the HNSW traversal using the matching set. Without an index, the planner has no choice but to evaluate the predicate for every candidate the traversal visits, and it cannot prune segments. The cost difference can be orders of magnitude for a selective filter on a large collection, because the indexed version visits a small fraction of the graph while the unindexed version visits many more nodes looking for matches. The results are identical because the filter is a semantic predicate; the index is an implementation detail that does not change the set of matching points, only the cost of finding them.
The mechanism that makes this possible is that Qdrant separates the logical filter (the predicate) from the physical execution (the index). The filter is expressed in the API as a set of conditions; the planner chooses how to evaluate them based on the available indexes and the statistics. If a payload index exists on the field, the planner can use it. If not, it falls back to scanning the payload. Both produce the same results because the predicate is evaluated the same way; only the execution differs. This is a common source of confusion because the query API looks the same, the results look the same, and the performance difference is invisible in the results. It only shows up in latency, and it is easy to misattribute the difference to something else (the vector search, the data, the network) because the index is not visible in the query. The practical implication is that the indexing decision must be based on the query patterns, not on the results, and it must be revisited as the query patterns change. A field that is not indexed today may become a bottleneck when a new query pattern filters on it.
Same results: the filter is a predicate; the index does not change the matching set.
Different execution: indexed fields use the index; unindexed fields scan the payload.
Selectivity: the performance gap grows with the selectivity of the filter.
Segment pruning: an index can prune segments that cannot match; a scan cannot.
Traversal guidance: an index can guide the HNSW traversal; a scan forces more exploration.
Invisibility: the index does not appear in the query or the results, only in the latency.
Indexing decisions: based on query patterns, not on the data.
Monitoring: track which fields are filtered on and how often, to decide what to index.
The trade-off is between the cost of the index and the cost of the scan. An index consumes memory and slows writes; a scan is slower to query but has no indexing cost. For a field that is filtered on frequently and selectively, the index is worth it. For a field that is rarely filtered on, the scan is acceptable. The common mistakes are: (1) not indexing a field that is filtered on frequently, so queries are slow; (2) indexing every field defensively, so memory and write cost are high for no benefit; (3) not revisiting the indexing decisions as query patterns change; (4) assuming the performance difference is caused by the vector search when it is caused by the filter; (5) not testing the query with and without the index to quantify the difference. Version note: the payload index types and the planner's behavior have evolved across Qdrant releases. The exact performance difference between an indexed and unindexed filter depends on the version. Benchmark on your version with your data.
Version-dependent: the payload index types and the planner's behavior have changed across Qdrant releases. The exact performance difference between an indexed and unindexed filter depends on the version and the selectivity. Benchmark on your version with your data.
You filter on a field that is not indexed and the query is slow. Explain what the engine is doing and what to add.
A teammate says the filter must be broken because it returns the right results but is slow. Explain the difference between correctness and performance.
You add an index to a field and the query gets faster but writes get slower. Describe the trade-off and how you would decide.
Two collections have the same data and the same filter, but one is 10x faster. Diagnose the difference.
Design a monitoring system that identifies fields that are filtered on but not indexed, and triggers an indexing review.
You need to reduce the latency of a filter-heavy workload by 50 percent. Describe the diagnosis and the levers.
Derive the break-even point where adding an index to a field is worth the memory and write cost, as a function of query frequency and selectivity.
You are designing a query planner that must decide between index-based and scan-based execution for each filter clause. Describe the cost model.